package org.ruogu.netty.handler; import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.util.CharsetUtil; import java.nio.charset.Charset; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LeanerServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> { private static final Logger LOG = LoggerFactory.getLogger(LeanerServerHandler.class); @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { QueryStringDecoder queryDecoder = new QueryStringDecoder(request.getUri()); final String uri = request.getUri(); HttpMethod method = request.getMethod(); // 请求参数 Map<String, String> params = null; // GET if (method == HttpMethod.GET) { Map<String, List<String>> getParams = queryDecoder.parameters(); params = parseParams(getParams); } // POST else if (method == HttpMethod.POST) { ByteBuf content = request.content(); if (content.isReadable()) { String param = content.toString(Charset.forName("UTF-8")); QueryStringDecoder postQueryStringDecoder = new QueryStringDecoder("/?" + param); Map<String, List<String>> postParams = postQueryStringDecoder.parameters(); params = parseParams(postParams); } } final String path = queryDecoder.path(); LOG.info("req, path:" + path + ", method:" + method + ", uri:" + uri); LOG.info("params:" + params.toString()); writeResponse(request, ctx); } private void writeResponse(FullHttpRequest request, ChannelHandlerContext ctx) { // Build the response object. FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, request.getDecoderResult().isSuccess() ? OK : BAD_REQUEST); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); StringBuilder buf = new StringBuilder(); buf.append("Hello\n"); buf.append("world!\n"); ByteBuf buffer = Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8); response.content().writeBytes(buffer); buffer.release(); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } private Map<String, String> parseParams(Map<String, List<String>> qParams) { Map<String, String> params = null; if (!qParams.isEmpty()) { params = new HashMap<String, String>(); for (Entry<String, List<String>> p : qParams.entrySet()) { String key = p.getKey(); String value = p.getValue().get(0); params.put(key, value); } } return params; } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // Close the connection when an exception is raised. LOG.warn("Unexpected exception from downstream.", cause); ctx.close(); } }